package com.gubatian.jdk.analyse.register.client;

import java.util.UUID;

/**
 * 在服务上被创建和启动，负责跟register-server通信
 * @author gubatian
 * @date 2021/9/7 4:24 下午
 */
public class RegisterClient {
    private String SERVICE_NAME = "inventory-service";
    private String ip = "192.168.1.128";
    private String hostname = "inventory01";
    private int port = 9000;

    private String serviceInstanceId;
    private volatile Boolean isRunning;
    private HeartbeatWork heartbeatWork;
    /**
     * 拉取注册表
     */
    private ClientCachedServiceRegistry clientCachedServiceRegistry;
    /**
     * http通信组建
     */
    private HttpSender httpSender;
    public RegisterClient() {
        this.serviceInstanceId = UUID.randomUUID().toString().replace("-", "");
        this.httpSender = new HttpSender();
        this.isRunning = true;
        this.heartbeatWork = new HeartbeatWork(this, httpSender);
        this.clientCachedServiceRegistry = new ClientCachedServiceRegistry(this, httpSender);
    }
    public void start() {
        // 一旦启动了这个组件之后，他就负责在服务上干两个事情
        // 第一个事情，就是开启一个线程向register-server去发送请求，注册这个服务
        // 第二个事情，就是在注册成功之后，就会开启另外一个线程去发送心跳

        // 我们来简化一下这个模型
        // 我们在register-client这块就开启一个线程
        // 这个线程刚启动的时候，第一个事情就是完成注册
        try {
            RegisterClientWork registerClientWork = new RegisterClientWork();
            registerClientWork.start();
            // 等待注册线程注册成功
            registerClientWork.join();
        } catch (InterruptedException e) {
            e.printStackTrace();
        }
        // 如果注册完成了之后，他就会开启心跳线程
        // 每隔30秒就发送一个请求去进行心跳
        heartbeatWork.initialize();

        // 服务注册成功后拉取注册表
        clientCachedServiceRegistry.initialize();

    }

    /**
     * 负责向register-server发送请求的线程
     * @author gubatian
     * @date 2021/9/7 4:12 下午
     */
    private class RegisterClientWork extends Thread {
        public RegisterClientWork() {
            httpSender = new HttpSender();
        }

        @Override
        public void run() {
            // 应该是获取当前机器的信息
            // 包括当前机器的ip地址、hostname，以及你配置这个服务监听的端口号
            // 从配置文件里可以拿到
            RegisterRequest registerRequest = new RegisterRequest();
            registerRequest.setServiceName(SERVICE_NAME);
            registerRequest.setIp(ip);
            registerRequest.setHostname(hostname);
            registerRequest.setPort(port);
            registerRequest.setServiceInstanceId(serviceInstanceId);

            RegisterResponse response = httpSender.register(registerRequest);

            if (!RegisterResponse.SUCCESS.equals(response.getStatus())) {
                return;
            }
            System.out.println("服务实例【" + registerRequest + "】，注册成功......");
        }
    }

    /**
     * 关闭心跳线程
     */
    public void shutdown() {
        isRunning = false;
        heartbeatWork.destroy();
        clientCachedServiceRegistry.destroy();
        httpSender.cancel(SERVICE_NAME, serviceInstanceId);
    }

    /**
     * 获取运行状态
     * @return
     */
    public boolean isRunning() {
        return isRunning;
    }

    public String getServiceInstanceId() {
        return serviceInstanceId;
    }
}
